﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GameLayer : MonoBehaviour, IPointerDownHandler, IPointerClickHandler
{
    private static GameLayer s_Inst;
    public static GameLayer Instance
    {
        get { return s_Inst; }
    }

    private const int Chu_Pai_Time = 5;

    public Button m_BtnSetting;
    public Button m_BtnClose;

    public MjSitPlayerView[] m_SitPlayerViews;

    public Text m_TxtTime;
    public Text m_TxtCardNum;
    public RectTransform m_RtfChuPaiHint;

    public GameObject m_GoAction;
    public Button m_BtnGang;
    public Button m_BtnPeng;
    public Button m_BtnChi;
    public Button m_BtnHu;
    public Button m_BtnGuo;
    private Button[] m_ActionBtns = new Button[4];

    private int m_Status = 0; //1_发牌中, 2_打牌中, 3_显示结果
    //private int m_ChuIndex; //出牌人
    private float m_ChuPaiEndTime; //出牌结束时间
    private bool m_IsSelfChu;

    public MjRound m_Round;// = new MjRound();
    private int m_MyIndex = 0;
    private MjSitPlayer[] m_SitPlayers = new MjSitPlayer[4];
    private int m_LeftCardNum;
    private RectTransform m_UpCardRtf;

    public GameLayer()
    {
        if (null == s_Inst)
            s_Inst = this;
        else
            Debug.LogError($"{GetType().Name}:multi Instance");
    }

    void OnDestroy()
    {
        if (s_Inst == this)
            s_Inst = null;
        RegistMsg(false);
    }

    void Start()
    {
        m_BtnClose.onClick.AddListener(OnClick_Close);
        m_BtnSetting.onClick.AddListener(OnClick_Setting);
        m_BtnGang.onClick.AddListener(OnClick_Gang);
        m_BtnPeng.onClick.AddListener(OnClick_Peng);
        m_BtnChi.onClick.AddListener(OnClick_Chi);
        m_BtnHu.onClick.AddListener(OnClick_Hu);
        m_BtnGuo.onClick.AddListener(OnClick_Guo);

        for (int i = 0; i < m_SitPlayers.Length; ++i)
        {
            var sitPlayer = new MjSitPlayer((eMjSitIndex)i);
            m_SitPlayers[i] = sitPlayer;
        }
    }

    void OnEnable()
    {
        RegistMsg(true);
    }

    void OnDisable()
    {
        RegistMsg(false);
    }

    private void OnClick_Close() { }

    private void OnClick_Setting()
    {
        if (m_Round.IsAllReady())
            return;

        m_Round.SetReady(eMjSitIndex.East);
        m_Round.SetReady(eMjSitIndex.North);
        m_Round.SetReady(eMjSitIndex.West);
        m_Round.SetReady(eMjSitIndex.South);

        if (!m_Round.IsAllReady())
            return;

        m_Round.StartFaPai();
    }

    private void OnClick_Gang()
    {
    }

    private void OnClick_Peng()
    {
        m_Round.Peng();
        m_GoAction.SetActive(false);
    }

    private void OnClick_Chi()
    {
        m_Round.Chi();
        m_GoAction.SetActive(false);
    }

    private void OnClick_Hu()
    {
    }

    private void OnClick_Guo()
    {
        m_Round.Pass();
        m_GoAction.SetActive(false);
    }

    void Update()
    {
        switch (m_Status)
        {
        case 2:
            if (m_ChuPaiEndTime > 0)
            {
                float leftTime = m_ChuPaiEndTime - Time.realtimeSinceStartup;
                if (leftTime <= 0)
                {
                    leftTime = 0;
                    m_ChuPaiEndTime = 0;
                    //时间到没出牌
                    //m_Round.ChuPaiDefault();
                }
                m_TxtTime.text = $"{Mathf.CeilToInt(leftTime)}s";
            }
            break;
        }
    }

    //******************** message

    private void RegistMsg(bool b)
    {
        if (b)
        {
            MsgDispatch.Instance.AddReceiver("Mj.ActionNoti", OnMsg_ActionNoti);
        }
        else
        {
            MsgDispatch.Instance.RemoveReceivers(this);
        }
    }

    private void OnMsg_ActionNoti(string msg, object obj)
    {
        var data = (MjActionData)obj;
        //data.m_RoundId;
        switch ((eMjAction)data.m_Action)
        {
        case eMjAction.Start:
        {
            m_LeftCardNum = MjCard.GetMaxCardNum();
            m_TxtCardNum.text = $"{m_LeftCardNum}张";

            var mySitPlayer = m_SitPlayers[m_MyIndex];
            foreach (var id in data.m_CardIds)
            {
                var c = MjCard.GetCard(id);
                mySitPlayer.StartFaPai(c);
            }
            mySitPlayer.RoundFaPai(MjCard.GetCard(data.m_CardId));

            //其余3位的牌, 我看不到, 均用空牌填充
            for (int i = 1; i < 4; ++i)
            {
                var sitPlayer = m_SitPlayers[i];
                for (int j = 0; j < 13; ++j)
                {
                    sitPlayer.StartFaPai(MjCard.Empty);
                }
            }
            StartCoroutine(StartAnim());
            break;
        }

        case eMjAction.Fa:
        {
            m_LeftCardNum--;
            m_TxtCardNum.text = $"{m_LeftCardNum}张";
            SetChuIndex(data.m_Index);

            var sitPlayer = m_SitPlayers[data.m_Index];
            var sitPlayerView = m_SitPlayerViews[data.m_Index];
            if (data.m_Index == m_MyIndex)
            {
                m_IsSelfChu = true;
                sitPlayerView.SetCardClickable(true);

                var c = MjCard.GetCard(data.m_CardId);
                sitPlayer.RoundFaPai(c);
                sitPlayerView.ShowMoPaiCardNum(c);
            }
            else
            {
                m_IsSelfChu = false;
                sitPlayer.RoundFaPai(MjCard.Empty);
                sitPlayerView.ShowMoPaiCardBack();
            }
            break;
        }

        case eMjAction.Chu:
        {
            //貌似没必要验证
            //if (m_ChuIndex != data.m_Index) 
            //    Debug.LogWarning($"{m_ChuIndex} != {data.m_Index}");

            var c = MjCard.GetCard(data.m_CardId);
            var sitPlayer = m_SitPlayers[data.m_Index];

            var sitPlayerView = m_SitPlayerViews[data.m_Index];
            sitPlayerView.HideMoPaiCard();
            //刷新手牌的显示
            if (data.m_Index == m_MyIndex)
            {
                sitPlayer.RoundChuPai(c);
                sitPlayerView.SetCardClickable(false);

                if (null != m_UpCardRtf)
                {
                    //收回牌(比如: 点了牌之后, 超时没出牌, 自动出牌了)
                    var anPos = m_UpCardRtf.anchoredPosition;
                    anPos.y = -37.5f;
                    m_UpCardRtf.anchoredPosition = anPos;

                    //var chuCardView = m_ClickCardRtf.GetComponent<MjCardView>();
                    //chuCardView.m_Card = null;
                    m_UpCardRtf = null;
                }

                int i = 0;
                for (; i < sitPlayer.GetHandCardCount(); ++i)
                {
                    var handCard = sitPlayer.GetHandCard(i);
                    sitPlayerView.ShowHandCardNum(i, handCard);
                }
                for (; i < 13; ++i)
                {
                    sitPlayerView.HideHandCard(i);
                }
            }
            else
            {
                sitPlayer.RoundChuPai(c);
                for (int i = sitPlayer.GetHandCardCount() - 1; i < 13; ++i)
                {
                    sitPlayerView.HideHandCard(i);
                }

                if (null != data.m_NextAction)
                {
                    m_ActionBtns[0] = m_BtnGang;
                    m_ActionBtns[1] = m_BtnPeng;
                    m_ActionBtns[2] = m_BtnChi;
                    m_ActionBtns[3] = m_BtnHu;

                    m_GoAction.SetActive(true);
                    foreach (var action in data.m_NextAction)
                    {
                        m_BtnGuo.gameObject.SetActive(true);
                        switch ((eMjAction)action)
                        {
                        case eMjAction.Gang:
                            m_ActionBtns[0] = null;
                            m_BtnGang.gameObject.SetActive(true);
                            break;
                        case eMjAction.Peng:
                            m_ActionBtns[1] = null;
                            m_BtnPeng.gameObject.SetActive(true);
                            break;
                        case eMjAction.Chi:
                            m_ActionBtns[2] = null;
                            m_BtnChi.gameObject.SetActive(true);
                            break;
                        case eMjAction.Hu:
                            m_ActionBtns[3] = null;
                            m_BtnHu.gameObject.SetActive(true);
                            break;
                        }
                    }

                    foreach (var btn in m_ActionBtns)
                    {
                        if (null != btn)
                            btn.gameObject.SetActive(false);
                    }

                }
            }

            sitPlayerView.PushShowOutCard(c);
            break;
        }

        case eMjAction.Gang:
        {
            break;
        }

        case eMjAction.Peng:
        {
            //被碰的人(即: 刚刚出牌的人)
            var sitPlayer = m_SitPlayers[data.m_LastChuIndex];
            var cTemp = sitPlayer.PopLastChuCard();
            if (cTemp.Id != data.m_CardId)
            {
                Debug.LogWarning($"Peng: id not eq:{cTemp.Id} != {data.m_CardId}");
            }

            var sitPlayerView = m_SitPlayerViews[data.m_LastChuIndex];
            var c = MjCard.GetCard(data.m_CardId); //被碰的牌
            sitPlayerView.PopShowOutCard();

            //发起碰的人
            var sitPlayer_2 = m_SitPlayers[data.m_Index];
            sitPlayer_2.Peng(c, (eMjSitIndex)data.m_LastChuIndex, out var c1, out var c2);
            if (c1.Id != data.m_CardIds[0] || c2.Id != data.m_CardIds[1])
            {
                Debug.LogWarning($"Peng: id not eq: {c1.Id}, {data.m_CardIds[0]}; {c2.Id}, {data.m_CardIds[1]}");
            }

            var sitPlayerView_2 = m_SitPlayerViews[data.m_Index];
            if (data.m_Index == m_MyIndex)
            {
                //刷新手牌
                int i = 0;
                for (; i < sitPlayer_2.GetHandCardCount(); ++i)
                {
                    var handCard = sitPlayer_2.GetHandCard(i);
                    sitPlayerView_2.ShowHandCardNum(i, handCard);
                }
                for (; i < 13; ++i)
                {
                    sitPlayerView_2.HideHandCard(i);
                }
                //刷新附露
                for (int j = 0; j < sitPlayer_2.GetCardGroupCount(); ++j)
                {
                    var cg = sitPlayer_2.GetCardGroup(j);
                    sitPlayerView_2.ShowCardGroup(j, cg);
                }
            }
            else
            {
                
            }
            break;
        }

        case eMjAction.Chi:
        {
            break;
        }

        case eMjAction.Hu:
        {
            break;
        }

        }
    }

    //********************

    IEnumerator StartAnim()
    {
        m_Status = 1;

        MjSitPlayer mySitPlayer = null;
        MjSitPlayerView sitPlayerView = null;
        for (int i = 0; i < 3; ++i) //开局3次摸牌
        {
            mySitPlayer = m_SitPlayers[0];
            sitPlayerView = m_SitPlayerViews[0];
            for (int j = 0; j < 4; ++j) //每次4张牌
            {
                var cardIndex = (i * 4) + j;
                var handCard = mySitPlayer.GetHandCard(cardIndex);
                sitPlayerView.ShowHandCardNum(cardIndex, handCard);
            }
            m_LeftCardNum -= 4;
            m_TxtCardNum.text = $"{m_LeftCardNum}张";
            yield return new WaitForSeconds(0.5f);

            //其他3个人
            for (int j = 1; j < 4; ++j)
            {
                sitPlayerView = m_SitPlayerViews[j];
                for (int k = 0; k < 4; ++k)
                {
                    var cardIndex = (i * 4) + k;
                    sitPlayerView.ShowHandCardBack(cardIndex);
                }
                m_LeftCardNum -= 4;
                m_TxtCardNum.text = $"{m_LeftCardNum}张";
                yield return new WaitForSeconds(0.5f);
            }
        }

        //摸第13张牌以及第1张Round牌
        sitPlayerView = m_SitPlayerViews[0];
        {

            var handCard = mySitPlayer.GetHandCard(12);
            sitPlayerView.ShowHandCardNum(12, handCard);
            sitPlayerView.ShowMoPaiCardNum(mySitPlayer.LastFaCard);
        }
        m_LeftCardNum -= 2;
        m_TxtCardNum.text = $"{m_LeftCardNum}张";
        yield return new WaitForSeconds(0.5f);
        
        //理牌
        mySitPlayer.StartLiPai();
        for (int i = 0; i < mySitPlayer.GetHandCardCount(); ++i)
        {
            var handCard = mySitPlayer.GetHandCard(i);
            sitPlayerView.ShowHandCardNum(i, handCard);
        }

        //其他3个人
        for (int j = 1; j < 4; ++j)
        {
            sitPlayerView = m_SitPlayerViews[j];

            sitPlayerView.ShowHandCardBack(12);

            m_LeftCardNum -= 1;
            m_TxtCardNum.text = $"{m_LeftCardNum}张";
            yield return new WaitForSeconds(0.5f);
        }

        m_Status = 2;
        m_IsSelfChu = true;
        m_SitPlayerViews[0].SetCardClickable(true);
        SetChuIndex((int)eMjSitIndex.East);
    }

    void SetChuIndex(int sitIndex)
    {
        //m_ChuIndex = sitIndex;
        m_ChuPaiEndTime = Time.realtimeSinceStartup + Chu_Pai_Time;
        
        var leAngles = m_RtfChuPaiHint.localEulerAngles;
        leAngles.z = -90 + sitIndex * 90;
        m_RtfChuPaiHint.localEulerAngles = leAngles;
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (!m_IsSelfChu)
        {
            Debug.Log($"OnPointerDown: not self ChuPai");
            return;
        }

        var pressGo = eventData.pointerPressRaycast.gameObject;
        if (pressGo)
        {
            if (pressGo.name.StartsWith("Card"))
            {
                var cardRtf = (RectTransform)pressGo.transform;
                //点了另一张牌
                if (null != m_UpCardRtf && m_UpCardRtf != cardRtf)
                {
                    var anPos2 = m_UpCardRtf.anchoredPosition;
                    anPos2.y = -37.5f;
                    m_UpCardRtf.anchoredPosition = anPos2;
                }
                
                var anPos = cardRtf.anchoredPosition;
                if (anPos.y < -30) //第1次点击牌: 抬起牌
                {
                    m_UpCardRtf = cardRtf;
                    anPos.y = -7;
                    cardRtf.anchoredPosition = anPos;
                }
                else //抬起的牌再次点击: 牌打出去
                {
                    m_UpCardRtf = null;
                    anPos.y = -37.5f;
                    cardRtf.anchoredPosition = anPos;

                    var chuCardView = cardRtf.GetComponent<MjCardView>();
                    var chuCard = chuCardView.m_Card;
                    m_Round.ChuPai(chuCard.Id);
                    
                    //等服务器响应再隐藏并清掉所打的牌
                    //cardRtf.gameObject.SetActive(false);
                    //chuCardView.m_Card = null;
                }
            }
            else
            {
                if (null != m_UpCardRtf) //收回牌
                {
                    var anPos = m_UpCardRtf.anchoredPosition;
                    anPos.y = -37.5f;
                    m_UpCardRtf.anchoredPosition = anPos;
                    m_UpCardRtf = null;
                }
            }
        }
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log($"OnPointerClick:");
    }
}
